package com.share.mongo.repository

import cn.hutool.core.date.DateUtil
import cn.hutool.core.lang.Snowflake
import cn.hutool.core.util.RandomUtil
import cn.hutool.json.JSONUtil
import com.share.mongo.MongoApplication
import com.share.mongo.entity.Article
import lombok.extern.slf4j.Slf4j
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.boot.test.context.SpringBootTest
import org.springframework.boot.test.context.TestConfiguration
import org.springframework.context.annotation.Bean
import org.springframework.data.domain.Page
import org.springframework.data.domain.PageRequest
import org.springframework.data.domain.Sort
import org.springframework.data.mongodb.core.MongoTemplate
import org.springframework.data.mongodb.core.query.Criteria
import org.springframework.data.mongodb.core.query.Query
import org.springframework.data.mongodb.core.query.Update
import spock.lang.Specification
import spock.mock.DetachedMockFactory

import java.util.stream.Collectors

/**
 * @author caifan
 * @since 2021/3/29
 * description: 
 */
//@RunWith(SpringRunner.class)
@SpringBootTest(classes = [MongoApplication.class])
@Slf4j
class ArticleRepositoryTest extends Specification {

    @Autowired
    private ArticleRepository articleRepo;

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private Snowflake snowflake;

    def "testSave"() {
        Article article = new Article(2L, RandomUtil.randomString(20), RandomUtil.randomString(150), DateUtil.date(), DateUtil.date(), 0L, 0L);
        articleRepo.save(article)
//        log.info("【article】= {}", JSONUtil.toJsonStr(article));
        expect:
        articleRepo.count() > 0

    }

    /**
     *  批量添加
     */
    def "testSaveList"() {
        given: Integer len = 10
        List<Article> articleList = new ArrayList<>(len);
        for (int i = 0; i < 10; i++) {
            articleList.add(new Article(snowflake.nextId(), RandomUtil.randomString(20), RandomUtil.randomString(150), DateUtil.date(), DateUtil.date(), 0L, 0L));
        }
        articleRepo.saveAll(articleList);
        expect:
            articleRepo.count() > 10
    }

    /**
     * 测试更新
     */
    def "testUpdate"() {
        given: Long id = 1L
        articleRepo.findById(id).ifPresent({ article ->
            article.setTitle(article.getTitle() + "更新之后的标题");
            article.setUpdateTime(DateUtil.date());
            articleRepo.save(article);
            printf("【article】= %s", JSONUtil.toJsonStr(article));
        })
    }

    /**
     *  删除测试
     * @return
     */
    def "testDelete"() {
        given: Long id = 1L
        articleRepo.deleteById(id)// 根据主键删除
    }

    /**
     * 测试点赞数、访客数，使用save方式更新点赞、访客
     */
    def "testThumbUp"() {
        articleRepo.findById(1L).ifPresent({ article ->
            article.setThumbUp(article.getThumbUp() + 1);
            article.setVisits(article.getVisits() + 1);
            articleRepo.save(article);
            printf("【标题】= %s【点赞数】= %d【访客数】= %d", article.getTitle(), article.getThumbUp(), article.getVisits());
        });
        expect:
            articleRepo.findById(1L) != null
    }

    /**
     * 测试点赞数、访客数，使用更优雅/高效的方式更新点赞、访客
     */
    def "testThumbUp2"() {
        given: Long id = 1L
        Query query = new Query();
        query.addCriteria(Criteria.where("_id").is(id));
        Update update = new Update();
        update.inc("thumbUp", id);
        update.inc("visits", id);
        mongoTemplate.updateFirst(query, update, "article");

        articleRepo.findById(id).ifPresent({ article -> printf("【标题】= %s【点赞数】= %d【访客数】= %s", article.getTitle(), article.getThumbUp(), article.getVisits()) });
    }

    /**
     * 测试分页排序查询
     */
    def "testQuery"() {
        given: int page = 0; int size = 5
        Sort sort = Sort.by("thumbUp", "updateTime").descending();
        PageRequest pageRequest = PageRequest.of(page, size, sort);
        Page<Article> all = articleRepo.findAll(pageRequest);
        printf("【总页数】= %d", all.getTotalPages());
        printf("【总条数】= %d", all.getTotalElements());
        printf("【当前页数据】= %s", JSONUtil.toJsonStr(all.getContent().stream().map({ article -> "文章标题：" + article.getTitle() + "点赞数：" + article.getThumbUp() + "更新时间：" + article.getUpdateTime() }).collect(Collectors.toList())));
    }

    /**
     * 测试根据标题模糊查询
     */
    def "testFindByTitleLike"() {
        given: String title = "更新"
        List<Article> articles = articleRepo.findByTitleLike(title);
        printf("【articles】= %s", JSONUtil.toJsonStr(articles));
    }


    def "testAAA"() {
        given: def name = "张三"
        println name + "hello"
    }

    @TestConfiguration
    static class MockConfig {
        def detachedMockFactory = new DetachedMockFactory()

        @Bean
        MongoTemplate mongoTemplate1() {
            return detachedMockFactory.Stub(HelloWorldService)
        }
    }

}
